package com.mindata.blockchain.core.controller;

import com.mindata.blockchain.block.Instruction;
import com.mindata.blockchain.common.ResultPack;
import com.mindata.blockchain.common.exception.BlockException;
import com.mindata.blockchain.core.bean.BaseData;
import com.mindata.blockchain.core.bean.ResultGenerator;
import com.mindata.blockchain.core.manager.DbBlockManager;
import com.mindata.blockchain.core.requestbody.InstructionBody;
import com.mindata.blockchain.core.service.InstructionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 区块body内单个指令的controller
 *
 * @author wuweifeng wrote on 2018/3/7.
 */
@RestController
@RequestMapping("/instruction")
@Api(description = "指令操作")
public class InstructionController {
    @Resource
    private InstructionService instructionService;
    @Resource
    private DbBlockManager dbBlockManager;

    /**
     * 构建一条指令，传入各必要参数,并且把指令加入指令池中
     *
     * @param instructionBody instructionBody
     * @return 用私钥签名后的指令
     */
    @PostMapping
    @ApiOperation(value = "构建一条指令，并且把指令加入指令池中")
    public BaseData build(@ApiParam(value = "区块指令", defaultValue = "{\"instructionId\":\"983ce0bc870147a38e74a0a1fcef790c\",\"json\":\"{\\\"content\\\":\\\"json\\\",\\\"origin\\\":\\\"xiaomi\\\",\\\"target\\\":\\\"mz\\\"}\",\"oldJson\":\"{\\\"content\\\":\\\"oldJson\\\",\\\"origin\\\":\\\"old_origin\\\",\\\"target\\\":\\\"old_target\\\"}\",\"operation\":2,\"privateKey\":\"rVvENnLasAaISMISNPxCTRMB3ZI5G6Rn414Az6h/Bd8=\",\"publicKey\":\"AzgMeAsYiQl7ndl7gL91kBWGZGOp9oIlzBaLTwuL4Zpn\",\"table\":\"message\"}")
                          @RequestBody InstructionBody instructionBody) throws Exception {

        String coinBasePubKey = dbBlockManager.getCoinBasePubKey();
        if (StringUtils.isBlank(coinBasePubKey)) {
            throw new BlockException("节点无法生成指令，先创建账户");
        }

        ResultPack<String> resultPack = instructionService.checkContent(instructionBody);
        if (resultPack.isFailed()) {
            return ResultGenerator.genFailResult(resultPack.comment());
        }
        Instruction instruction = instructionService.build(instructionBody);

        ResultPack<String> result = instructionService.addPendingInstructions(instruction);
        if (result.isFailed()) {
            return ResultGenerator.genFailResult(result.comment());
        }
        return ResultGenerator.genSuccessResult(instruction);
    }
}
